package br.com.character.flex.chorm.core.annotation
{
    
    import br.com.character.flex.chorm.core.sql.Field;
    import br.com.character.flex.chorm.core.sql.IField;
    
    import flash.utils.describeType;
    import flash.utils.getDefinitionByName;
    import flash.utils.getQualifiedClassName;
    
    import mx.collections.ArrayCollection;

    [Bindable]
    public class AnnotationParser implements IAnnotationParser
    {
        private var _dto:Object;
        private var _annotation:IAnnotation;
        
        public function AnnotationParser(d:Object=null)
        {
            _dto = d;
        }

        public function get annotation():IAnnotation
        {
            return _annotation;
        }

        public function set annotation(value:IAnnotation):void
        {
            _annotation = value;
        }

        public function get dto():Object
        {
            return _dto;
        }

        public function set dto(value:Object):void
        {
            _dto = value;
        }

        public function parser():IAnnotation
        {
            return annotation;
        }
        
        private static function getFieldsByObject(object:Object) : XMLList
        {
            var className:String = getQualifiedClassName(object);
            var type:Class = Class(getDefinitionByName(className));
            var xml:XML = describeType(new type());
            return xml.accessor;
        }

        public static function getAnnotationsByDTO(obj:Object) : Vector.<IField>  {
            var result:Vector.<IField> = new Vector.<IField>();
            var annotations:Vector.<IAnnotation> = null;
            var fields : XMLList = getFieldsByObject(obj);
            for (var i : int = 0; i < fields.length(); i++) {
                var field:IField = new Field();
                annotations = getAnnotationsByFieldMetadata(fields[i].metadata);
                field.annotations = annotations;
                result.push(field);
            }
            return result;
        }
        
        public static function getAnnotationsByField(field:XML) : Vector.<IAnnotation> {
            var fieldMetadata:XMLList = field.metadata;
            var annotations: Vector.<IAnnotation> = getAnnotationsByFieldMetadata(fieldMetadata);
            return annotations;
        }
        
        public static function getAnnotationsByFieldMetadata(fieldMetadata:XMLList) : Vector.<IAnnotation> {
            var result:Vector.<IAnnotation>  = new Vector.<IAnnotation>();
            var annotation:IAnnotation = null;
            var attributes: Vector.<IAttribute> = null;
            for each (var annotationXML:XML in fieldMetadata){
                annotation = new Annotation();
                annotation.name = annotationXML.@name;
                attributes = getAttributesByMetadata(annotationXML.metadata);
                annotation.attributes = attributes;
                result.push(annotation);
            }
            return result;
        }
        
        public static function getAttributesByMetadata(annotationMetadata:XMLList) : Vector.<IAttribute> {
            var result:Vector.<IAttribute> = new Vector.<IAttribute>();
            var attr:IAttribute = null;
            for (var i:int = 0; i<annotationMetadata.length(); i++) {
                attr = new Attribute();
                attr.name  = annotationMetadata[i].@key;
                attr.value = annotationMetadata[i].@value;
                result.push(attr);
            }
            return result;
        }
    }
}